Description: Fix segfault writing ascii .vtu files with implicit cell type arrays
NewIterator() returns nullptr for the implicit cell-type arrays used
- since VTK 9.6. WriteAsciiData() dereferenced that nullptr via an
- unconditional iter->Delete(). Guard it. Closes yade FTBFS.
+ since VTK 9.6, so WriteAsciiData() dereferenced that nullptr in
+ iter->Delete(). Merely guarding the Delete() is not enough: the
+ templated writer already returns early on a null iterator, so the array
+ is then written empty, and since WriteInlineData() discards the return
+ value the writer reports success for a file which has lost all of its
+ cells. Write such arrays through an explicit copy instead.
+ Closes yade FTBFS.
Forwarded: not-yet
Author: Anton Gladky <gladk@debian.org>
===================================================================
--- vtk9.orig/IO/XML/vtkXMLWriter.cxx
+++ vtk9/IO/XML/vtkXMLWriter.cxx
-@@ -1978,7 +1978,10 @@ int vtkXMLWriter::WriteAsciiData(vtkAbs
+@@ -34,6 +34,7 @@
+ #include "vtkOutputStream.h"
+ #include "vtkPointData.h"
+ #include "vtkPoints.h"
++#include "vtkSmartPointer.h"
+ #include "vtkStdString.h"
+ #include "vtkStreamingDemandDrivenPipeline.h"
+ #include "vtkStringFormatter.h"
+@@ -1968,6 +1969,15 @@ int vtkXMLWriteAsciiData(ostream& os, it
+ int vtkXMLWriter::WriteAsciiData(vtkAbstractArray* a, vtkIndent indent)
+ {
+ vtkArrayIterator* iter = a->NewIterator();
++ vtkSmartPointer<vtkAbstractArray> copy;
++ if (!iter)
++ {
++ // Arrays which provide no iterator, such as the implicit arrays used since VTK 9.6
++ // for uniform cell types, are written through an explicit copy.
++ copy.TakeReference(vtkAbstractArray::CreateArray(a->GetDataType()));
++ copy->DeepCopy(a);
++ iter = copy->NewIterator();
++ }
+ ostream& os = *(this->Stream);
+ int ret;
+ switch (a->GetDataType())
+@@ -1978,7 +1988,10 @@ int vtkXMLWriter::WriteAsciiData(vtkAbst
ret = 0;
break;
}
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkUnstructuredGrid.h>
+#include <vtkXMLUnstructuredGridReader.h>
#include <vtkXMLUnstructuredGridWriter.h>
+#include <iostream>
+
int main()
{
vtkNew<vtkPoints> points;
writer->SetDataModeToAscii();
writer->Write();
+ // the cell types have to be written, not only not to crash: an empty types
+ // array makes the reader silently drop every cell of the file
+ vtkNew<vtkXMLUnstructuredGridReader> reader;
+ reader->SetFileName("a.vtu");
+ reader->Update();
+ const vtkIdType cellCount = reader->GetOutput()->GetNumberOfCells();
+ if (cellCount != 3)
+ {
+ std::cerr << "read back " << cellCount << " cells instead of 3\n";
+ return EXIT_FAILURE;
+ }
+
return EXIT_SUCCESS;
}
EOF